<?php


namespace App\Http\Services;

use Illuminate\Support\Facades\Redis;

/**
 * Class BoardExtendServices 记录限时比心礼物每人每天送出\收到数量，中和排行榜数据
 * @package App\Http\Services
 */
class BoardExtendServices
{
    //比心送礼物 每人每天 送出个数 HSAH
    private $TimedGiftSendoutCountKey = 'TIMEDGIFT.SENDOUT.COUNT.%s';
    // 比心送礼物 每人每天 收到个数 HSAH
    private $TimedGiftReceivedCountKey = 'TIMEDGIFT.RECEIVED.COUNT.%s';
    // 比心送礼物 每人每天 兑换比心值次数（10♥比心兑换1点） HSAH
    private $TimedGiftBoardLockKey = 'TIMEDGIFT.SENDOUT.LOCK.%s.%s';

    // 比心礼物 goods_type
    const TimedGoodsType = 3;
    /*
    charts_user_charm 美魅力榜
     * */
    /**
     * 获取单日单人比心礼物 送出数量 key
     * @param $timeStr 日期串 20220802
     */
    private function getSendoutCountKey($timeStr){
        return sprintf($this->TimedGiftSendoutCountKey, $timeStr);
    }

    /**
     * 获取单日单人比心礼物 收到数量 key
     * @param $timeStr 日期串 20220802
     */
    private function getReceivedCountKey($timeStr){
        return sprintf($this->TimedGiftReceivedCountKey, $timeStr);
    }
    /**
     * 获取单日单人比心值 加锁key
     * @param $timeStr 日期串 20220802
     */
    private function getBoardLockKey($boardType, $timeStr){
        if (empty($boardType)|| empty($timeStr)){
            return false;
        }
        return sprintf($this->TimedGiftBoardLockKey,$boardType ,$timeStr);
    }

    /**
     * 设置过期时间
     * @param $key
     * @param $time 有效时间
     */
    public function expire($key, $time=0)
    {
        if (Redis::TTL($key) == -1) {
            $time = 48 * 3600;
            Redis::EXPIRE($key, $time);
        }
    }

    /**
     * 计算 比心礼物最大可兑换分数
     * @param $giftNum 比心计时礼物数量
     * @return false|float|int  最大分数
     */
    public function calcTimedGiftScore($giftNum)
    {
        $total = 0;
        # 比心值 兑换关闭
        if (false && $giftNum>=0){
            # 是否增加比心分数
            $ratio = 0.5;// 10比心兑换1点比心值
            $exchangeTimes = 10;// 每天没人最多兑换100点比心值
            $total = floor($giftNum * $ratio);
            if ($total > $exchangeTimes){
                $total = $exchangeTimes;
            }
        }
        return $total;
    }

    /**
     * 记录 比心礼物没人每天 送出收到数量
     * @param $sendUserId
     * @param int $ReceivedUserId
     * @param int $count
     * @return bool
     */
    public function recordBoardHeart($sendUserId, $ReceivedUserId,$count=1){
        $timeStr = date('Ymd');

        try {

            $sendKey = $this->getSendoutCountKey($timeStr);
            $ReceivedKey = $this->getReceivedCountKey($timeStr);
            if (empty($sendKey) || empty($ReceivedKey)){
                throw new Exception("获取key错误");
            }

            Redis::HINCRBY($sendKey, $sendUserId, $count);
            Redis::HINCRBY($ReceivedKey, $ReceivedUserId, $count);

            //设置已完成用户 48小时到期
            $this->expire($sendKey);
            $this->expire($ReceivedKey);


        } catch (\Exception $e) {
            $msg = $e->getMessage();
            write_log('BoardExtendServices'.(isCli()?'-cli':''), '[ERROR] 处理记录-recordBoardHeart', func_get_arg());
            return false;
        }



        return true;
    }

    /**
     * 当天榜单增加笔芯值
     * @param $boardType 榜单类型
     * @param $userId    榜单对用用户ID
     * @param array $count
     */
    public function handleBoardHeart($boardType='', $userId)
    {
        $timeStr = date('Ymd');
        $score = 0;
        try {
            if ($userId<=0){
                throw new \Exception("用户ID必需");
            }
            $lockKey = '';
            $hKey = '';

            switch ($boardType) {
                case 'SendGift':
                    $lockKey = $this -> getBoardLockKey($boardType, $timeStr);
                    // 财富榜  统计送礼人
                    $hKey = $this->getSendoutCountKey($timeStr);
                    break;

                case 'ReceivedGift':
                    $lockKey = $this -> getBoardLockKey($boardType, $timeStr);
                    // 人气榜  统计收礼人
                    $hKey = $this->getReceivedCountKey($timeStr);
                    break;


                default:
                    throw new \Exception("排行榜无需处理比心值");
                    break;
            }




            if (empty($hKey) || empty($lockKey)){
                throw new \Exception("获取key错误".$boardType);
            }

            $userGiftNum = Redis::hget($hKey,$userId);
            $lockCount = Redis::hget($lockKey,$userId);

            // 当天最多可兑换分数
            $todayMaxScore = $this -> calcTimedGiftScore($userGiftNum);
            if ($todayMaxScore>0 && $todayMaxScore>$lockCount){
                $score = $todayMaxScore-$lockCount;// 本次增加比心分数值（正常情况下1次+1）
                Redis::HINCRBY($lockKey, $userId, $score);
                //设置已完成用户 48小时到期
                $this->expire($lockKey);
            }

        } catch (\Exception $e) {
            $msg = $e->getMessage();
            write_log('BoardExtendServices'.(isCli()?'-cli':''), '[ERROR] 处理记录-handleBoardHeart', [$msg, func_get_arg()]);
            return false;
        }
        write_log('BoardExtendServices'.(isCli()?'-cli':''), '[INFO] 处理记录 handleBoardHeart-'.$boardType, ['score'=>$score,'userGiftNum'=>$userGiftNum,'lockCount'=>$lockCount,'total'=>$todayMaxScore,'userId'=>$userId]);

        return ['score'=>$score];
    }

}